#include <stdatomic.h>
#include <mthread.h>
#include <sys/syscall.h>

int mthread_spin_init(mthread_spinlock_t *lock)
{
    /* TODO: */
    return 0;
}
int mthread_spin_destroy(mthread_spinlock_t *lock) {
    // do nothing.
    return 0;
}
int mthread_spin_trylock(mthread_spinlock_t *lock)
{
    /* TODO: return 0 or EBUSY */
}
int mthread_spin_lock(mthread_spinlock_t *lock)
{
    /* TODO: */
}
int mthread_spin_unlock(mthread_spinlock_t *lock)
{
    /* TODO: */
    return 0;
}

int mthread_mutex_init(mthread_mutex_t *lock)
{
    /* TODO: */
    lock->binsem_id = binsemget((int)lock);
    return 0;
}
int mthread_mutex_destroy(mthread_mutex_t *lock) {
    // do nothing!
    return 0;
}
int mthread_mutex_trylock(mthread_mutex_t *lock) {
    /* TODO: */
    return 0;
}
int mthread_mutex_lock(mthread_mutex_t *lock) {
    /* TODO: */
    binsemop(lock->binsem_id, BINSEM_OP_LOCK);
    return 0;
}
int mthread_mutex_unlock(mthread_mutex_t *lock)
{
    /* TODO: */
    binsemop(lock->binsem_id, BINSEM_OP_UNLOCK);
    return 0;
}

int mthread_barrier_init(mthread_barrier_t * barrier, unsigned count)
{
    // TODO:
    barrier->barrier_id = barrierget((int)barrier, count);
    return 0;
}
int mthread_barrier_wait(mthread_barrier_t *barrier)
{
    // TODO:
    barrierop(barrier->barrier_id);    
    return 0;
}
int mthread_barrier_destroy(mthread_barrier_t *barrier)
{
    // TODO:
    barrier = NULL;
    return 0;
}

int mthread_cond_init(mthread_cond_t *cond)
{
    // TODO:
    cond->cond_id = condget((int)cond);
    return 0;
}
int mthread_cond_destroy(mthread_cond_t *cond) 
{
    // TODO:
    cond = NULL;
    return 0;
}
int mthread_cond_wait(mthread_cond_t *cond, mthread_mutex_t *mutex)
{
    // TODO:
    binsemop(mutex->binsem_id, BINSEM_OP_UNLOCK);
    condop(cond->cond_id, COND_OP_WAIT);
    binsemop(mutex->binsem_id, BINSEM_OP_LOCK);
    return 0;
}
int mthread_cond_signal(mthread_cond_t *cond)
{
    // TODO:
    condop(cond->cond_id, COND_OP_SIGNAL);
    return 0;
}
int mthread_cond_broadcast(mthread_cond_t *cond)
{
    // TODO:
    condop(cond->cond_id, COND_OP_BROADCAST);
    return 0;
}

int mthread_semaphore_init(mthread_semaphore_t *sem, int val)
{
    // TODO:
    return 0;
}
int mthread_semaphore_up(mthread_semaphore_t *sem)
{
    // TODO:
    return 0;
}
int mthread_semaphore_down(mthread_semaphore_t *sem)
{
    // TODO:
    return 0;
}
int mthread_semaphore_destroy(mthread_semaphore_t *sem)
{
    // TODO:
    return 0;
}